AVL平衡二叉树的各种问题(Balanced Binary Tree)

AVL树或者是一棵空树,或者是具有以下性质的非空二叉搜索树:

1. 任一结点的左、右子树均为AVL树;

2.根结点左、右子树高度差的绝对值不超过1.

 

1.声明

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
typedef int ElementType;
typedef struct AVLNode * AVLTree; //AVL树类型 
struct AVLNode{
    ElementType Data;    //结点数据 
    AVLTree Left;        //左子树 
    AVLTree Right;        //右子树 
    int Height;         //树高 
};
View Code

2.获取高度

int GetHeight(AVLTree T){
    if(T) return max(GetHeight(T->Left ),GetHeight(T->Right )) + 1;
    else return 0;
}
View Code

3.左单旋LL

AVLTree SingleLeftRotation(AVLTree A){
    // 注意:A 必须有一个左子结点 B
    // 将 A 与 B 左单选,更新 A 与 B 的高度,返回新的根结点 B 
    AVLTree B = A->Left ;
    A->Left = B->Right ;
    B->Right  = A;
    A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1;
    B->Height = max(GetHeight(B->Left ),A->Height ) + 1;
    return B;
}
View Code

4.右单旋RR

AVLTree SingleRightRotation(AVLTree A){
    AVLTree B = A->Right ;
    A->Right  = B->Left ;
    B->Left   = A;
    A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1;
    B->Height = max(GetHeight(B->Right ),A->Height ) + 1;
    return B;
}
View Code

5.左-右双旋LR

AVLTree DoubleLeftRightRotation(AVLTree A){
    // 注意:A必须有一个左子结点 B,且 B必须有一个右子结点 C
    // 将 A、B 与 C 做两次单旋,返回新的根结点 C
    
    //将 B 与 C 做右单旋,C被返回 
    A->Left = SingleRightRotation(A->Left );
    //将 A 与 C 做左单旋,C被返回 
    return SingleLeftRotation(A);
}
View Code

6.右-左双旋RL

AVLTree DoubleRightLeftRotation(AVLTree A){
    A->Right = SingleLeftRotation(A->Right );
    return SingleRightRotation(A);
}
View Code

7.AVL树的插入

AVLTree Insert(AVLTree T, ElementType X){
    //将 X 插入AVL树 T 中,并且返回调整后的AVL树 
    if(! T){ //若插入空树,则新建包含一个结点的树 
        T = (AVLTree)malloc(sizeof(struct AVLNode));
        T->Data  = X;
        T->Height = 1;
        T->Left = T->Right = NULL;
    }
    else if(X < T->Data ){
        // 插入 T 的左子树 
        T->Left =Insert(T->Left , X);
        // 如果需要左旋 
        if(GetHeight(T->Left ) - GetHeight(T->Right )== 2)
            if(X <T->Left ->Data)
                T = SingleLeftRotation(T); //左单旋 
            else
                T = DoubleLeftRightRotation(T); //左-右双旋 
    }  
    else if(X > T->Data ){
        // 插入 T 的右子树 
        T->Right  = Insert(T->Right , X);
        // 如果需要右旋 
        if(GetHeight(T->Left ) - GetHeight(T->Right )== -2)
            if(X > T->Right ->Data)
                T = SingleRightRotation(T); //右单选 
            else
                T = DoubleRightLeftRotation(T); //右-左双旋 
    }
    // else X==T->Data 无需插入
    
    //更新树高 
    T->Height = max(GetHeight(T->Left ),GetHeight(T->Right )) + 1;
    return T;
}
View Code

完整测试:

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
typedef int ElementType;
typedef struct AVLNode * AVLTree;
struct AVLNode{
    ElementType Data;
    AVLTree Left;
    AVLTree Right;
    int Height; 
};
int GetHeight(AVLTree T){
    if(T) return max(GetHeight(T->Left ),GetHeight(T->Right )) + 1;
    else return 0;
}
AVLTree SingleLeftRotation(AVLTree A){
    AVLTree B = A->Left ;
    A->Left = B->Right ;
    B->Right  = A;
    A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1;
    B->Height = max(GetHeight(B->Left ),A->Height ) + 1;
    return B;
}
AVLTree SingleRightRotation(AVLTree A){
    AVLTree B = A->Right ;
    A->Right  = B->Left ;
    B->Left   = A;
    A->Height = max(GetHeight(A->Left ), GetHeight(A->Right )) + 1;
    B->Height = max(GetHeight(B->Right ),A->Height ) + 1;
    return B;
}
AVLTree DoubleLeftRightRotation(AVLTree A){
    A->Left = SingleRightRotation(A->Left );
    return SingleLeftRotation(A);
}
AVLTree DoubleRightLeftRotation(AVLTree A){
    A->Right = SingleLeftRotation(A->Right );
    return SingleRightRotation(A);
}
AVLTree Insert(AVLTree T, ElementType X){
    if(! T){
        T = (AVLTree)malloc(sizeof(struct AVLNode));
        T->Data  = X;
        T->Height = 1;
        T->Left = T->Right = NULL;
    }
    else if(X < T->Data ){
        T->Left =Insert(T->Left , X);
        if(GetHeight(T->Left ) - GetHeight(T->Right )== 2)
            if(X <T->Left ->Data)
                T = SingleLeftRotation(T);
            else
                T = DoubleLeftRightRotation(T);
    }
    else if(X > T->Data ){
        T->Right  = Insert(T->Right , X);
        if(GetHeight(T->Left ) - GetHeight(T->Right )== -2)
            if(X > T->Right ->Data)
                T = SingleRightRotation(T);
            else
                T = DoubleRightLeftRotation(T);
    }
    T->Height = max(GetHeight(T->Left ),GetHeight(T->Right )) + 1;
    return T;
}
void LevelorderTravelsal(AVLTree BT){
    queue<AVLTree> q;
    AVLTree T;
    if(!BT) return;
    q.push(BT);
    while(!q.empty()){
        T=q.front();
        q.pop();
        cout<<T->Data <<" ";
        if(T->Left ) q.push(T->Left );
        if(T->Right ) q.push(T->Right );
    }
} 
int main(){
    int n; cin>>n;
    AVLTree T = NULL;
    for(int i=0;i<n;i++){
        int x; cin>>x;
        T = Insert(T, x);
    }
    LevelorderTravelsal(T);
}
View Code

 

posted @ 2018-12-08 17:09  莫莫君不恋爱  阅读(354)  评论(0编辑  收藏  举报